using B.S.Medical.Api.Read.Application.Command.DoctorSchedule;
using B.S.Medical.Api.Read.DTOS;
using B.S.Medical.Domain.Medical;
using B.S.Medical.Domain.Doctor;
using B.S.Medical.Domain.Department;
using B.S.Medical.Infrastructure.Interface;
using MediatR;
using System.Linq;
using B.S.Medical.ErrorCode;

namespace B.S.Medical.Api.Read.Application.Handler.DoctorSchedule
{
    public class GetDoctorDayScheduleHandler : IRequestHandler<GetDoctorDayScheduleCommand, ApiResult<DoctorDayScheduleDto>>
    {
        private readonly IBaseRepository<DoctorScheduleModel> _scheduleRepo;
        private readonly IBaseRepository<DoctorModel> _doctorRepo;
        private readonly IBaseRepository<ManageModel> _departmentRepo;
        private readonly IBaseRepository<RegisterModel> _registerRepo;

        public GetDoctorDayScheduleHandler(
            IBaseRepository<DoctorScheduleModel> scheduleRepo,
            IBaseRepository<DoctorModel> doctorRepo,
            IBaseRepository<ManageModel> departmentRepo,
            IBaseRepository<RegisterModel> registerRepo)
        {
            _scheduleRepo = scheduleRepo;
            _doctorRepo = doctorRepo;
            _departmentRepo = departmentRepo;
            _registerRepo = registerRepo;
        }

        public async Task<ApiResult<DoctorDayScheduleDto>> Handle(GetDoctorDayScheduleCommand request, CancellationToken cancellationToken)
        {
            var doctor = _doctorRepo.GetAll().FirstOrDefault(d => d.Id == request.DoctorId);
            if (doctor == null)
            {
                return new ApiResult<DoctorDayScheduleDto> { Code = ApiEnum.Fail, Msg = "医生不存在" };
            }
            var department = _departmentRepo.GetAll().FirstOrDefault(dep => dep.Id == doctor.DepartmentId);

            // 查询当天上午/下午排班
            var schedules = _scheduleRepo.GetAll()
                .Where(s => s.DoctorId == request.DoctorId && s.ScheduleDate == request.Date)
                .ToList();

            // 查询当天有效预约
            var validStatus = new[] { "待就诊", "已就诊" };
            var registers = _registerRepo.GetAll()
                .Where(r => r.DoctorId == request.DoctorId && r.VisitDate.Date == request.Date.Date && validStatus.Contains(r.Status))
                .ToList();

            // 上午
            var am = schedules.FirstOrDefault(s => s.Period == 1);
            var amCount = registers.Count(r => r.AppointmentTime.Hour < 12);
            // 下午
            var pm = schedules.FirstOrDefault(s => s.Period == 2);
            var pmCount = registers.Count(r => r.AppointmentTime.Hour >= 12);

            var dto = new DoctorDayScheduleDto
            {
                DoctorId = doctor.Id,
                DoctorName = doctor.DoctorName,
                DepartmentName = department?.DepartmentName ?? string.Empty,
                AM = new DayPeriodDetailDto
                {
                    TimeRange = am?.StartTime.HasValue == true && am?.EndTime.HasValue == true
                        ? $"{am.StartTime.Value:HH:mm}-{am.EndTime.Value:HH:mm}" : "8:00-12:00",
                    SlotCount = am?.SlotCount ?? 0,
                    AppointmentCount = amCount,
                    IsAvailable = am?.IsAvailable ?? false
                },
                PM = new DayPeriodDetailDto
                {
                    TimeRange = pm?.StartTime.HasValue == true && pm?.EndTime.HasValue == true
                        ? $"{pm.StartTime.Value:HH:mm}-{pm.EndTime.Value:HH:mm}" : "14:00-18:00",
                    SlotCount = pm?.SlotCount ?? 0,
                    AppointmentCount = pmCount,
                    IsAvailable = pm?.IsAvailable ?? false
                }
            };

            return new ApiResult<DoctorDayScheduleDto>
            {
                Code = ApiEnum.Success,
                Data = dto
            };
        }
    }
} 